package com.ming.mallchat.common.chat.service.adapter;

import cn.hutool.core.bean.BeanUtil;
import com.ming.mallchat.common.chat.domain.vo.req.ChatMessageReq;
import com.ming.mallchat.common.chat.domain.vo.req.msg.TextMsgReq;
import com.ming.mallchat.common.chat.domain.vo.resp.ChatMessageResp;
import com.ming.mallchat.common.chat.enums.MessageMarkTypeEnum;
import com.ming.mallchat.common.chat.enums.MessageStatusEnum;
import com.ming.mallchat.common.chat.enums.MessageTypeEnum;
import com.ming.mallchat.common.chat.pojo.Message;
import com.ming.mallchat.common.chat.pojo.MessageMark;
import com.ming.mallchat.common.chat.service.strategy.msg.AbstractMsgHandler;
import com.ming.mallchat.common.chat.service.strategy.msg.MsgHandlerFactory;
import com.ming.mallchat.common.common.domain.enums.YesOrNoEnum;
import com.ming.mallchat.common.user.service.handler.MsgHandler;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 86150
 * @date 2023/10/12
 */
public class MessageAdapter {
    public static Message buildMsgSave(ChatMessageReq request, Long uid) {
        return Message.builder()
                .fromUid(uid)
                .roomId(request.getRoomId())
                .type(request.getMsgType())
                .status(MessageStatusEnum.NORMAL.getStatus())
                .build();
    }

    public static List<ChatMessageResp> buildMsgResp(List<Message> messages, Map<Long, Message> replyMap, List<MessageMark> msgMark, Long receiveUid) {
        Map<Long, List<MessageMark>> markMap = msgMark.stream().collect(Collectors.groupingBy(MessageMark::getMsg_id));
        return messages.stream().map(a -> {
            ChatMessageResp resp = new ChatMessageResp();
            resp.setFromUser(buildFromUser(a.getFromUid()));
            resp.setMessage(buildMessage(a, replyMap, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid));
            return resp;
        }).collect(Collectors.toList());
    }

    private static ChatMessageResp.Message buildMessage(Message message, Map<Long, Message> replyMap, List<MessageMark> marks, Long receiveUid) {
        ChatMessageResp.Message msg = new ChatMessageResp.Message();
        BeanUtil.copyProperties(message, msg);
        msg.setSendTime(message.getCreateTime());
        msg.setReplyMessage(buildMessage(new ArrayList<>(replyMap.values())));
        AbstractMsgHandler msgHandler = MsgHandlerFactory.getStrategyNoNull(message.getType());
        if (Objects.nonNull(msgHandler)) {
            msg.setBody(msgHandler.showMsg(message));
        }
        //消息标记
        msg.setMessageMark(buildMsgMark(marks, receiveUid));
        return msg;
    }

    private static ChatMessageResp.MessageMark buildMsgMark(List<MessageMark> marks, Long receiveUid) {
        Map<Integer, List<MessageMark>> typeMap = marks.stream().collect(Collectors.groupingBy(MessageMark::getType));
        List<MessageMark> likeMarks = typeMap.getOrDefault(MessageMarkTypeEnum.LIKE.getType(), new ArrayList<>());
        List<MessageMark> dislikeMarks = typeMap.getOrDefault(MessageMarkTypeEnum.DISLIKE.getType(), new ArrayList<>());
        ChatMessageResp.MessageMark mark = new ChatMessageResp.MessageMark();
        mark.setLikeCount(likeMarks.size());
        mark.setDislikeCount(dislikeMarks.size());
        mark.setUserLike(Optional.ofNullable(receiveUid).filter(uid -> likeMarks.stream().anyMatch(a -> Objects.equals(a.getUid(), receiveUid))).map(a -> YesOrNoEnum.YES.getStatus()).orElse(YesOrNoEnum.NO.getStatus()));
        mark.setUserDislike(Optional.ofNullable(receiveUid).filter(uid -> dislikeMarks.stream().anyMatch(a -> Objects.equals(a.getUid(), receiveUid))).map(a -> YesOrNoEnum.YES.getStatus()).orElse(YesOrNoEnum.NO.getStatus()));
        return mark;
    }

    private static List<ChatMessageResp.Message> buildMessage(List<Message> replyList) {
        return replyList.stream().map(a -> {
            ChatMessageResp.Message messageVO = new ChatMessageResp.Message();
            messageVO.setType(a.getType());
            messageVO.setId(a.getId());
            messageVO.setRoomId(a.getRoomId());
            messageVO.setBody(a.getContent());
            messageVO.setSendTime(a.getCreateTime());
            return messageVO;
        }).collect(Collectors.toList());
    }


    private static ChatMessageResp.UserInfo buildFromUser(Long fromUid) {
        return new ChatMessageResp.UserInfo(fromUid);
    }

    public static ChatMessageReq buildAgreeMsg(Long roomId) {
        return ChatMessageReq.builder()
                .msgType(MessageTypeEnum.TEXT.getType())
                .roomId(roomId)
                .body(TextMsgReq.builder().content("我们已经成为好友了，开始聊天吧").build())
                .build();
    }
}
